package com.conversationboard.filedownload;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.conversationboard.config.Configuration;
import com.conversationboard.model.Board;
import com.conversationboard.model.Boards;
import com.conversationboard.model.User;

@WebServlet(name = "FileDownloadServlet", urlPatterns = "/files/*")
public class FileDownloadServlet extends HttpServlet {

	private static final long serialVersionUID = -1968701932633707577L;
	private static final Pattern fileNamePattern = Pattern.compile("/files/(.*?)-(.*?)/(.*)$", (Pattern.DOTALL));


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		OutputStream out = response.getOutputStream();

		try {

			/* Extract the requested filename from the URL */

			Matcher matcher = fileNamePattern.matcher(request.getRequestURI());

			if (!matcher.find()) {
				return;
			}

			String fileName = matcher.group(1) + "-" + matcher.group(2);
			int boardId = Integer.parseInt(matcher.group(1));

			String mimeType = MimeTypes.get(request.getRequestURI());

			response.setContentType(mimeType);

			Board board = Boards.getBoard(boardId);

			/*
			 * If the board that this document was posted from is a private
			 * board, then only users with access to that private board should
			 * be able to see it, so we must have a logged in user, and that
			 * user must have access to the given board.
			 */

			if (board.isPrivateBoard()) {

				if (request.getUserPrincipal() == null) {
					return;
				}

				User user = User.get(request.getUserPrincipal());

				if (!user.canRead(boardId)) {
					return;
				}
			}

			/* Read the file and stream it to the output stream */

			File file = new File(Configuration.getInstance().getFileUploadRepository() + "/" + fileName);

			byte[] buffer = FileUtils.readFile(file);
			DownloadUtils.writeToNetwork(buffer, out);

		} catch (MimeTypeException e) {
			throw new ServletException(e);
		} catch (NumberFormatException e) {
		} catch (SQLException e) {
			throw new ServletException(e);
		} finally {
			out.close();
		}
	}

}
